package edu.cicese.tm;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;

/**
 * Created by: Eduardo Quintana Contreras
 * Date: 31/10/11
 * Time: 07:24 PM
 */
public class FrameTest extends JFrame {
	public JPanel pMain, pTag1, pTag2;
	public JTextField txtImage;
//	public JTextField txtJSON;
	public JTextArea txtJSON;
	public JButton btnLoad, btnPoints, btnPrev, btnNext;
	private BufferedImage originalLoadedImage, cachedLoadedImage, tagImage1, tagImage2;
	private String imageLoadingDir;
	private String[] lines;
	private int currentIndex = 0;
	private JLabel lblInfo = new JLabel();

	public FrameTest() {
//		frmMain = father;
//		frmSpace = this;
		setSize(1020, 700);
		setResizable(false);
		setLayout(null);
		setIconImage(new ImageIcon(getClass().getClassLoader().getResource("icons/icon.png")).getImage());

		initComponents();
		setVisible(true);
	}

	private void initComponents() {
		pMain = new JPanel() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				g.drawImage(cachedLoadedImage, 0, 0, null);
			}
		};
		pMain.setBackground(Color.WHITE);
		pMain.setLayout(null);
		pMain.setBounds(5, 5, 800, 600);
		cachedLoadedImage = (BufferedImage)createImage(800, 600);

		pTag1 = new JPanel() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				g.drawImage(tagImage1, 0, 0, null);
			}
		};
		pTag1.setBackground(Color.WHITE);
		pTag1.setLayout(null);
		pTag1.setBounds(825, 150, 150, 150);
		tagImage1 = (BufferedImage)createImage(150, 150);
		
		pTag2 = new JPanel() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				g.drawImage(tagImage2, 0, 0, null);
			}
		};
		pTag2.setBackground(Color.WHITE);
		pTag2.setLayout(null);
		pTag2.setBounds(825, 320, 150, 150);
		tagImage2 = (BufferedImage)createImage(150, 150);

/*		btnLoad = new JButton();
		addButton(btnLoad, 5, 620, 32, 32, "Cargar imagen", "addImg", null, getContentPane());
		btnLoad.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				loadImage();
			}
		});*/

		btnPoints = new JButton();
		addButton(btnPoints, 40, 620, 32, 32, "Procesar", "edit", null, getContentPane());
		btnPoints.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				loadString();
			}
		});

		btnPrev = new JButton();
		addButton(btnPrev, 780, 620, 32, 32, "Anterior", "back", null, getContentPane());
		btnPrev.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				previous();
			}
		});

		btnNext = new JButton();
		addButton(btnNext, 820, 620, 32, 32, "Siguiente", "play", null, getContentPane());
		btnNext.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				next();
			}
		});

//		txtJSON = new JTextField();
//		txtJSON.setBounds(80, 620, 700, 30);

		txtJSON = new JTextArea();
		txtJSON.setBounds(80, 620, 700, 30);

		lblInfo.setBounds(825, 10, 200, 30);
		lblInfo.setFont(new Font("Sans Serif", Font.BOLD, 15));

		getContentPane().add(pMain);
		getContentPane().add(lblInfo);
		getContentPane().add(pTag1);
		getContentPane().add(pTag2);
		getContentPane().add(txtJSON);
	}

	public void loadString() {
		String txtString = txtJSON.getText();
		lines = txtString.split("\n");
		process(0);
		currentIndex = 0;
	}

	public void process(int index) {
		try {
			String txtString = lines[index];

			String image = txtString.substring(0, 3);

			BufferedImage img = ImageIO.read(new File("D:\\Tests\\Pasitos\\objects\\_alltestimages\\" + image + ".JPG"));
			Graphics2D g2d = (Graphics2D)pMain.getGraphics();
			BufferedImage tempImg = (BufferedImage)createImage(800, 600);
			Graphics2D tempG = (Graphics2D)tempImg.getGraphics();
			tempG.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
			tempG.drawImage(img, 0, 0, 800, 600, null);
			tempG.dispose();
			g2d.drawImage(tempImg, null, 0, 0);
			originalLoadedImage = cachedLoadedImage = tempImg;

			String space1 = txtString.substring(4, 6);
			String tagID1 = txtString.substring(7, 10);

			String space2 = txtString.substring(11, 13);
			String tagID2 = txtString.substring(14, 17);

			img = ImageIO.read(new File("D:\\Pasitos\\ans-tm\\spaces\\" + space2 + "\\tags\\matched\\" + tagID2 + "\\" + tagID2 + ".png"));
			g2d = (Graphics2D) pTag2.getGraphics();
			tempImg = (BufferedImage)createImage(150, 150);
			tempG = (Graphics2D)tempImg.getGraphics();
			tempG.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
			tempG.drawImage(img, 0, 0, 150, 150, null);
			tempG.dispose();
			g2d.drawImage(tempImg, null, 0, 0);
			tagImage2 = tempImg;

			lblInfo.setText(image);

			if (space1.compareTo("00") != 0) {
				img = ImageIO.read(new File("D:\\Pasitos\\ans-tm\\spaces\\" + space1 + "\\tags\\matched\\" + tagID1 + "\\" + tagID1 + ".png"));
				g2d = (Graphics2D) pTag1.getGraphics();
				tempImg = (BufferedImage)createImage(150, 150);
				tempG = (Graphics2D)tempImg.getGraphics();
				tempG.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
				tempG.drawImage(img, 0, 0, 150, 150, null);
				tempG.dispose();
				g2d.drawImage(tempImg, null, 0, 0);
				tagImage1 = tempImg;


				int beginPos = txtString.indexOf("{");
				String json = txtString.substring(beginPos);


				loadPoints(json);

			}
			else {
				lblInfo.setText(image + " No tag found");
				System.out.println(image + " No tag found...  " + System.currentTimeMillis());
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void previous() {
		if (currentIndex > 0) {
			process(--currentIndex);
		}
	}

	public void next() {
		if (currentIndex < lines.length - 1) {
			process(++currentIndex);
		}
	}

	public void loadPoints(String json) {
		JSONObject joArea = (JSONObject) JSONValue.parse(json);
		JSONArray jaPoints = (JSONArray)joArea.get("points");
		if (jaPoints != null) {
			Graphics2D g2d = (Graphics2D)pMain.getGraphics();
			BufferedImage tempImg = (BufferedImage)createImage(800, 600);
			Graphics2D tempG = (Graphics2D)tempImg.getGraphics();
			tempG.drawImage(originalLoadedImage, 0, 0, null);
			tempG.setStroke(new BasicStroke(4f));

			tempG.setColor(new Color(250, 125, 0, 150));
			int x, y;

			JSONObject joPoint;
			for (int i = 0; i < jaPoints.size(); i++) {
				joPoint = (JSONObject)jaPoints.get(i);
				x = Integer.parseInt(joPoint.get("x").toString());
				y = Integer.parseInt(joPoint.get("y").toString());
				tempG.fillOval(x - 3, y - 3, 6, 6);
			}

			tempG.dispose();

			g2d.drawImage(tempImg, null, 0, 0);
			cachedLoadedImage = tempImg;

		}
		else {
			lblInfo.setText(lblInfo.getText() + " No tag found*");
			System.out.println(lblInfo.getText() + " No tag found...  " + System.currentTimeMillis());
		}
	}
	
	public void loadImage() {
		JFileChooser fcPlanImg = new JFileChooser();
		PreviewPane previewPane = new PreviewPane();
		fcPlanImg.setAccessory(previewPane);
		fcPlanImg.addPropertyChangeListener(previewPane);
		FileNameExtensionFilter extensionFilter = new FileNameExtensionFilter("Imágenes .JPG y .PNG", "jpg", "png");
		fcPlanImg.setFileFilter(extensionFilter);
		fcPlanImg.setFileSelectionMode(JFileChooser.FILES_ONLY);
		if (imageLoadingDir != null) {
			fcPlanImg.setCurrentDirectory(new File(imageLoadingDir));
		}
		if (fcPlanImg.showDialog(this, "Abrir") == JFileChooser.APPROVE_OPTION) {
			// change the plan image
			try {
//				BufferedImage img;
//				File planImg = new File(fcPlanImg.getSelectedFile().getCanonicalPath());
//				if (planImg.exists()){
//					img = ImageIO.read(planImg);
//					BufferedImage tempImg = (BufferedImage)createImage(800, 600);
//					Graphics2D tempG = (Graphics2D)tempImg.getGraphics();
//					tempG.drawImage(img.getScaledInstance(800, 600, Image.SCALE_AREA_AVERAGING), 0, 0, null);
//					tempG.dispose();
//					originalPlanImage = tempImg;
//					planImage = tempImg;
//				}


				BufferedImage img = ImageIO.read(new File(fcPlanImg.getSelectedFile().getCanonicalPath()));
				Graphics2D g2d = (Graphics2D)pMain.getGraphics();
				BufferedImage tempImg = (BufferedImage)createImage(800, 600);
				Graphics2D tempG = (Graphics2D)tempImg.getGraphics();
				tempG.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
				tempG.drawImage(img, 0, 0, 800, 600, null);
				tempG.dispose();
				g2d.drawImage(tempImg, null, 0, 0);
				originalLoadedImage = cachedLoadedImage = tempImg;


				try {
					imageLoadingDir = fcPlanImg.getCurrentDirectory().getCanonicalPath();
				} catch (IOException e) {
					e.printStackTrace();
				}

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	//! Adds a JButton
	private void addButton(JButton button, int x, int y, int width, int height,
	                       String toolTipText, String iconName, JPanel pane, Container container) {
		Icon icon = new ImageIcon(getClass().getClassLoader().getResource("icons/" + iconName + ".png"));
		Icon rIcon = new ImageIcon(getClass().getClassLoader().getResource("icons/" + iconName + "O.png"));
		Icon pIcon = new ImageIcon(getClass().getClassLoader().getResource("icons/" + iconName + "P.png"));
		SwingUtil.addButton(button, x, y, width, height, toolTipText, icon, rIcon, pIcon, pane, container);
	}
	
	static class PreviewPane extends JPanel implements PropertyChangeListener {
		private JLabel lblImgPreview;
		private int maxImgWidth;
		public PreviewPane() {
			setLayout(new BorderLayout(5, 5));
			setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
			add(new JLabel("Vista previa:"), BorderLayout.NORTH);
			lblImgPreview = new JLabel();
			lblImgPreview.setBackground(Color.WHITE);
			lblImgPreview.setOpaque(true);
			lblImgPreview.setPreferredSize(new Dimension(400, 400));
			maxImgWidth = 395;
			lblImgPreview.setBorder(BorderFactory.createEtchedBorder());
			add(lblImgPreview, BorderLayout.CENTER);
		}

		public void propertyChange(PropertyChangeEvent evt) {
			Icon icon = null;
			if(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(evt.getPropertyName())) {
				File newFile = (File)evt.getNewValue();
				if(newFile != null) {
					String path = newFile.getAbsolutePath();
					if(path.toLowerCase().endsWith(".jpg") || path.endsWith(".png")) {
						try {
							BufferedImage img = ImageIO.read(newFile);
							float width = img.getWidth();
							float height = img.getHeight();
							float scale = height / width;
							width = maxImgWidth;
							height = (width * scale); // height should be scaled from new width
							icon = new ImageIcon(img.getScaledInstance(
									Math.max(1, (int)width), Math.max(1, (int)height), Image.SCALE_FAST));
						}
						catch(IOException e) {
							// couldn't read image.
						}
					}
				}

				lblImgPreview.setIcon(icon);
				this.repaint();
			}
		}
	}
}
